// Copyright (C) 2005 Taylor L. Riché <riche@cs.utexas.edu>
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// 	$Id: Events.java 111 2005-08-10 19:10:25Z richetl $	
//

import java.io.*;
import java.util.*;

class Events
{
    class Event
    {
	public static final int PUB = 0;
	public static final int SUB = 1;

	private int declType;
	private String type;
	private String func;

	public Event(int dt, String t, String f) {
	    if(dt == PUB) {
		assert(f == null);
	    }
	    declType = dt;
	    type = t;
	    func = f;
	}

	public int getDeclType() {
	    return declType;
	}
	public String getType() {
	    return type;
	}
	public String getFunc() {
	    assert(declType == SUB);
	    return func;
	}
	public void printPublish(PrintStream file) {
	    if(declType == PUB) {
		file.println("\tvoid pub_" + type + "(lee::Context * context, lee::Event * ev = NULL) {");
		file.println("\t\tif(ev == NULL) {");
		file.println("\t\t\tev = new lee::Event();");
		file.println("\t\t}");
		file.println("\t\tev->setEventType(" + type + ");");
		file.println("\t\tcontext->getEventList()->push_back(ev);");
		file.println("\t}");
	    }
	}

	public void printSubscribe(PrintStream file) {
	    if(declType == SUB) {
		file.println("\tvoid deliver_" + type + "(lee::Context * context, lee::Event * ev);");
	    }
	}

	public void printSubscribeSwitch(boolean first, PrintStream file) {
	    if(declType == SUB) {
		if(!first) {
		    file.print("\t\tif");
		}
		else {
		    file.print("\t\telse if");
		}
		file.println("(ev->getType() == \"" + type + "\") {");
		file.println("\t\t\tdeliver_" + type + "(context, ev);");
		file.println("\t\t}");
	    }
	}

	public void printRegister(PrintStream file) {
	    if(declType == SUB) {
		file.println("\t\tmasterSub->registerSub(this, " + type + ");");
	    }
	}
    }

    private LinkedList eventList;

    public Events() {
	eventList = new LinkedList();
    }

    public void printPublish(PrintStream file) {
	Iterator events = eventList.iterator();
	int listSize = eventList.size();
	file.println();
	for(int i = 0; i < listSize; i++) {
	    Event event = (Event)events.next();
	    event.printPublish(file);
	}
    }

    public void printSubscribeSwitch(PrintStream file) {
	file.println("\tvirtual deliver(lee::Context * context, lee::Event * ev) {");
	Iterator events = eventList.iterator();
	int listSize = eventList.size();
	file.println();
	for(int i = 0; i < listSize; i++) {
	    Event event = (Event)events.next();
	    if(i == 0) {
		event.printSubscribeSwitch(true, file);
	    }
	    else {
		event.printSubscribeSwitch(false, file);
	    }
	}
	file.println("\t}");
	file.println();
	file.println("\tvirtual registerSubs(lee::Subscription * masterSub) {");
	events = eventList.iterator();
	for(int i = 0; i < listSize; i++) {
	    Event event = (Event)events.next();
	    event.printRegister(file);
	}
	file.println("\t}");

    }

    public void printSubscribe(PrintStream file) {
	Iterator events = eventList.iterator();
	int listSize = eventList.size();
	file.println();
	for(int i = 0; i < listSize; i++) {
	    Event event = (Event)events.next();
	    event.printSubscribe(file);
	}
    }

    public void addEvent(Event ev) {
	eventList.addLast(ev);
    }
}
